package com.zbkj.client.callback;

import com.zbkj.client.enums.WebSocketEventType;
import com.zbkj.client.vo.CustomVoiceCjVo;
import com.zbkj.common.model.client.digital.CustomVoice;
import com.zbkj.service.service.CustomVoiceService;
import com.zbkj.common.utils.OssUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import com.zbkj.client.vo.CustomDpCjVo;
import com.zbkj.common.model.client.digital.CustomDigitalPerson;
import com.zbkj.service.service.CustomDigitalPersonService;
import com.zbkj.client.vo.DpVideoCjVo;
import com.zbkj.common.model.client.digital.DgVideo;
import com.zbkj.service.service.DgVideoService;
import com.zbkj.client.vo.DpVoiceCjVo;
import com.zbkj.common.model.client.digital.DpVoice;
import com.zbkj.service.service.DpVoiceService;
import com.zbkj.client.config.WebSocketSessionManager;
import com.alibaba.fastjson.JSON;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

import com.zbkj.client.task.CustomDpUrlUpdateTask;
import com.zbkj.client.task.CustomVoiceUrlUpdateTask;
import com.zbkj.client.task.DpVoiceUrlUpdateTask;
import com.zbkj.client.task.DpVideoUrlUpdateTask;

@Slf4j
@RestController
@RequestMapping("/dp")
public class DpController {
    @Autowired
    private CustomVoiceService customVoiceService;
    @Autowired
    private CustomDigitalPersonService customDigitalPersonService;
    @Autowired
    private DgVideoService dgVideoService;
    @Autowired
    private DpVoiceService dpVoiceService;
    @Autowired
    private WebSocketSessionManager webSocketSessionManager;
    @Autowired
    private CustomDpUrlUpdateTask customDpUrlUpdateTask;
    @Autowired
    private CustomVoiceUrlUpdateTask customVoiceUrlUpdateTask;
    @Autowired
    private DpVoiceUrlUpdateTask dpVoiceUrlUpdateTask;
    @Autowired
    private DpVideoUrlUpdateTask dpVideoUrlUpdateTask;

    /**
     * 定制声音-声音克隆回调
     * @param vo
     * @return
     */
    @PostMapping("/createCustomVoice")
    public String createCustomVoice(@RequestBody CustomVoiceCjVo vo) {
        try {
            log.info("接收到蝉镜声音回调数据: {}", vo);
            // 根据link_id查找并更新记录
            CustomVoice customVoice = customVoiceService.lambdaQuery()
                    .eq(CustomVoice::getLinkId, vo.getId())
                    .one();
            if (customVoice != null) {
                // 检查状态，如果已经更新过则直接返回
                if (customVoice.getStatus() != null && customVoice.getStatus() != 1) {
                    log.info("回调-定制声音已经更新, linkId: {}", vo.getId());
                    return "success";
                }
                
                // 更新字段
                customVoice.setName(vo.getName());
                customVoice.setAudioPath(vo.getAudio_path());
                customVoice.setStatus(vo.getStatus());
                customVoice.setLang(vo.getLang());
                customVoice.setErrMsg(vo.getErr_msg());
                customVoice.setProgress(vo.getProgress());
                customVoice.setUpdateTime(new Date());
                // type字段如果有可更新
                if (vo.getType() != null) customVoice.setType(vo.getType());

                customVoiceService.updateById(customVoice);
                
                // 确定事件名称
                String eventName;
                
                // status=2时异步上传OSS
                if (vo.getStatus() != null && vo.getStatus() == 2) {
                    eventName = WebSocketEventType.AddCustomVoiceSuccess.name();

                    // 异步上传OSS和更新数据库
                    customVoiceUrlUpdateTask.start(customVoice, vo);
                } else {
//                    eventName = "AddCustomVoiceFail";
                    eventName = WebSocketEventType.AddCustomVoiceFail.name();

                }
                
                // 推送WebSocket消息给前端
                Integer userId = customVoice.getUserId();
                if (userId != null) {
                    Map<String, Object> data = new HashMap<>();
                    data.put("id", customVoice.getId());
                    data.put("linkId", vo.getId());
                    data.put("status", vo.getStatus());
                    
                    Map<String, Object> message = new HashMap<>();
                    message.put("event", eventName);
                    message.put("data", data);
                    
                    String jsonMessage = JSON.toJSONString(message);
                    webSocketSessionManager.sendMessageToUser(userId, jsonMessage);
                    log.info("向用户 {} 推送定制声音状态更新: {}", userId, jsonMessage);
                }
                
                log.info("回调-更新定制声音成功，link_id: {}", vo.getId());
            } else {
                log.warn("未找到对应的定制声音记录，link_id: {}", vo.getId());
            }
            return "success";
        } catch (Exception e) {
            log.error("处理蝉镜声音回调异常", e);
            return "error";
        }
    }

    @PostMapping("/createCustomDp")
    public String createCustomDp(@RequestBody CustomDpCjVo vo) {
        try {
            log.info("接收到蝉镜回调数据: {}", vo);
            // 根据link_id查找并更新记录
            CustomDigitalPerson customDigitalPerson = customDigitalPersonService.lambdaQuery()
                    .eq(CustomDigitalPerson::getLinkId, vo.getId())
                    .one();
            if (customDigitalPerson != null) {
                // 1. 状态判断
                if (customDigitalPerson.getStatus() != null && customDigitalPerson.getStatus() != 1) {
                    log.info("回调-定制数字人形象已经更新, linkId: {}", vo.getId());
                    return "success";
                }

                // 原有字段更新逻辑
                customDigitalPerson.setName(vo.getName());
                customDigitalPerson.setType(vo.getType());
                customDigitalPerson.setPicUrl(vo.getPic_url());
                customDigitalPerson.setPreviewUrl(vo.getPreview_url());
                customDigitalPerson.setWidth(vo.getWidth());
                customDigitalPerson.setHeight(vo.getHeight());
                customDigitalPerson.setAudioManId(vo.getAudio_man_id());
                customDigitalPerson.setStatus(vo.getStatus());
                customDigitalPerson.setErrReason(vo.getErr_reason());
                customDigitalPerson.setIsOpen(vo.getIs_open());
                customDigitalPerson.setReason(vo.getReason());
                customDigitalPerson.setProgress(vo.getProgress());
                customDigitalPerson.setUpdateTime(new Date());

                customDigitalPersonService.updateById(customDigitalPerson);

                // 2. 事件名判断
                String eventName;

                // status=2时异步上传OSS
                if (vo.getStatus() != null && vo.getStatus() == 2) {
                    eventName = WebSocketEventType.AddCustomDpSuccess.name();
                    // 异步上传OSS和更新数据库
                    customDpUrlUpdateTask.start(customDigitalPerson, vo);
//                    CompletableFuture.runAsync(() -> customDpUrlUpdateTask.updateOssAndDb(customDigitalPerson, vo));
                } else {
                    //设置推送到ws事件的名
//                    eventName = "AddCustomDpFail";
                    eventName = WebSocketEventType.AddCustomDpFail.name();

                }

                // 3. WebSocket事件推送
                Integer userId = customDigitalPerson.getUserId();
                if (userId != null) {
                    Map<String, Object> data = new HashMap<>();
                    data.put("id", customDigitalPerson.getId());
                    data.put("linkId", vo.getId());
                    data.put("status", vo.getStatus());

                    Map<String, Object> message = new HashMap<>();
                    message.put("event", eventName);
                    message.put("data", data);

                    String jsonMessage = JSON.toJSONString(message);
                    webSocketSessionManager.sendMessageToUser(userId, jsonMessage);
                    log.info("向用户 {} 推送定制数字人状态更新: {}", userId, jsonMessage);
                }

                log.info("回调-更新定制数字人成功，link_id: {}", vo.getId());
            } else {
                log.warn("回调-未找到对应的定制数字人记录，link_id: {}", vo.getId());
            }
            return "success";
        } catch (Exception e) {
            log.error("处理蝉镜回调异常", e);
            return "error";
        }
    }

    /**
     * 合成视频，蝉镜回调地址
     * @param vo
     * @return
     */
    @PostMapping("/createDpVideo")
    public String createDpVideo(@RequestBody DpVideoCjVo vo) {
        try {
            log.info("接收到数字人视频回调数据: {}", vo);
            // 根据link_id查找并更新记录
            DgVideo dgVideo = dgVideoService.lambdaQuery()
                    .eq(DgVideo::getLinkId, vo.getId())
                    .one();
            if (dgVideo != null) {
                // 1. 状态判断
                if (dgVideo.getStatus() != null && dgVideo.getStatus() != 10) {
                    log.info("回调-定制数字人形象已经更新, linkId: {}", vo.getId());
                    return "success";
                }

                // 原有字段更新逻辑
                dgVideo.setVideoUrl(vo.getVideo_url());
                dgVideo.setSubtitleDataUrl(vo.getSubtitle_data_url());
                dgVideo.setPreviewUrl(vo.getPreview_url());
                dgVideo.setDuration(vo.getDuration());
                dgVideo.setStatus(vo.getStatus());
                dgVideo.setProgress(vo.getProgress());
                dgVideo.setMsg(vo.getMsg());
                dgVideo.setAudioUrls(vo.getAudio_urls());
                dgVideo.setUpdateTime(new Date());

                dgVideoService.updateById(dgVideo);

                // 2. 事件名判断
                String eventName;

                // status=30时异步上传OSS
                if (vo.getStatus() != null && vo.getStatus() == 30) {
//                    eventName = "AddDpVideoSuccess";
                    eventName = WebSocketEventType.AddDpVideoSuccess.name();
                    // 异步上传OSS和更新数据库
                    dpVideoUrlUpdateTask.start(dgVideo, vo);
                } else {
//                    eventName = "AddDpVideoFail";
                    eventName = WebSocketEventType.AddDpVideoFail.name();
                }

                // 3. WebSocket事件推送
                Integer userId = dgVideo.getUserId();
                if (userId != null) {
                    Map<String, Object> data = new HashMap<>();
                    data.put("id", dgVideo.getId());
                    data.put("linkId", vo.getId());
                    data.put("status", vo.getStatus());

                    Map<String, Object> message = new HashMap<>();
                    message.put("event", eventName);
                    message.put("data", data);

                    String jsonMessage = JSON.toJSONString(message);
                    webSocketSessionManager.sendMessageToUser(userId, jsonMessage);
                    log.info("向用户 {} 推送数字人视频状态更新: {}", userId, jsonMessage);
                }

                log.info("回调-更新数字人视频成功，link_id: {}", vo.getId());
            } else {
                log.warn("回调-未找到对应的数字人视频记录，link_id: {}", vo.getId());
            }
            return "success";
        } catch (Exception e) {
            log.error("处理数字人视频回调异常", e);
            return "error";
        }
    }

    /**
     * 合成声音，蝉镜回调地址
     * @param vo
     * @return
     */
    @PostMapping("/createDpVoice")
    public String createDpVoice(@RequestBody DpVoiceCjVo vo) {
        try {
            log.info("接收到蝉镜语音合成回调数据: {}", vo);
            // 根据link_id查找并更新记录
            DpVoice dpVoice = dpVoiceService.lambdaQuery()
                    .eq(DpVoice::getLinkId, vo.getId())
                    .one();
            if (dpVoice != null) {
                // 1. 检查状态，如果已经更新过则直接返回
                if (dpVoice.getStatus() != null && dpVoice.getStatus() != 1) {
                    log.info("回调-定制数字人形象已经更新, linkId: {}", vo.getId());
                    return "success";
                }
                
                // 2. 确定事件名称
                String eventName;
                
                // 更新字段
                dpVoice.setType(vo.getType());
                dpVoice.setStatus(vo.getStatus());
                dpVoice.setFocusTitles(vo.getFocus_titles());
                // 将text数组转换为字符串
                if (vo.getText() != null && !vo.getText().isEmpty()) {
                    dpVoice.setText(String.join(" ", vo.getText()));
                }
                dpVoice.setSlice(vo.getSlice());
                dpVoice.setErrMsg(vo.getErrMsg());
                dpVoice.setErrReason(vo.getErrReason());
                dpVoice.setSubtitles(vo.getSubtitles());
                // 将subtitles对象数组转换为字符串数组
//                if (vo.getSubtitles() != null && !vo.getSubtitles().isEmpty()) {
//                    List<String> subtitleStrings = vo.getSubtitles().stream()
//                            .map(subtitle -> {
//                                // 将对象转换为字符串，可以根据需要调整格式
//                                StringBuilder sb = new StringBuilder();
//                                if (subtitle.getKey() != null) sb.append("key:").append(subtitle.getKey()).append(" ");
//                                if (subtitle.getStart_time() != null) sb.append("start_time:").append(subtitle.getStart_time()).append(" ");
//                                if (subtitle.getEnd_time() != null) sb.append("end_time:").append(subtitle.getEnd_time());
//                                if (subtitle.getSubtitle() != null) sb.append("subtitle:").append(subtitle.getSubtitle());
//                                return sb.toString().trim();
//                            })
//                            .collect(Collectors.toList());
//                    dpVoice.setSubtitles(subtitleStrings);
//                }
                dpVoice.setUpdateTime(new Date());
                
                // 如果有full信息，更新相关字段
                if (vo.getFull() != null) {
                    dpVoice.setUrl(vo.getFull().getUrl());
                    dpVoice.setPath(vo.getFull().getPath());
                    dpVoice.setDuration(vo.getFull().getDuration());
                }

                //这里 更新数据库
                dpVoiceService.updateById(dpVoice);
                
                // status=9时异步上传OSS
                if (vo.getStatus() != null && vo.getStatus() == 9) {
//                    eventName = "AddDpVoiceSuccess";
                    eventName = WebSocketEventType.AddDpVoiceSuccess.name();
                    // 异步上传OSS和更新数据库
                    dpVoiceUrlUpdateTask.start(dpVoice, vo);
                } else {
//                    eventName = "AddDpVoiceFail";
                    eventName = WebSocketEventType.AddDpVoiceFail.name();
                }
                
                // 3. 推送WebSocket消息给前端
                Integer userId = dpVoice.getUserId();
                if (userId != null) {
                    Map<String, Object> data = new HashMap<>();
                    data.put("id", dpVoice.getId());
                    data.put("linkId", vo.getId());
                    data.put("status", vo.getStatus());
                    
                    Map<String, Object> message = new HashMap<>();
                    message.put("event", eventName);
                    message.put("data", data);
                    
                    String jsonMessage = JSON.toJSONString(message);
                    webSocketSessionManager.sendMessageToUser(userId, jsonMessage);
                    log.info("向用户 {} 推送数字人语音合成状态更新: {}", userId, jsonMessage);
                }
                
                log.info("回调-更新语音合成记录成功，link_id: {}", vo.getId());
            } else {
                log.warn("回调-未找到对应的语音合成记录，link_id: {}", vo.getId());
            }
            return "success";
        } catch (Exception e) {
            log.error("处理蝉镜语音合成回调异常", e);
            return "error";
        }
    }
} 